package device

import (
	"errors"
	"fmt"
	"go-iot/app/iot/core"
	"time"
	"go-iot/app/models"
	"go-iot/app/iot/network"
	"go-iot/app/common/mysql"
	networkmd "go-iot/app/models/network"
	"go-iot/app/common/logger"
	"gorm.io/gorm"
	"encoding/json"
)

// 分页查询设备
func PageProduct(page *models.PageQuery, createId int64) (*models.PageResult[models.Product], error) {
    var products []models.Product
    var total int64

    // 构建查询
    query := mysql.DB.Model(&models.Product{}).Where("create_id = ?", createId)

	// 添加条件过滤
    for _, condition := range page.Condition {
		query = query.Where(condition.Key+" = ?", condition.Value)
    }

    // 获取总数
    if err := query.Count(&total).Error; err != nil {
        return nil, fmt.Errorf("查询总数失败: %v", err)
    }

    // 执行分页查询
    if err := query.Order("create_time desc, id desc").
        Offset(page.PageOffset()).
        Limit(page.PageSize).
        Find(&products).Error; err != nil {
        return nil, fmt.Errorf("分页查询失败: %v", err)
    }

    result := models.PageUtil(total, page.PageNum, page.PageSize, products)
    return &result, nil
}

func ListAllProduct(createId int64) ([]models.Product, error) {
	var products []models.Product
	
	err := mysql.DB.Model(&models.Product{}).
		Select("id", "name", "type_id", "state", "store_policy", "desc", "create_id", "create_time").
		Where("create_id = ?", createId).
		Where("state = 1").
		Find(&products).Error
	
	if err != nil {
		return nil, fmt.Errorf("查询产品列表失败: %v", err)
	}
	
	return products, nil
}

func AddProduct(ob *models.ProductModel) error {
	if len(ob.Id) == 0 || len(ob.Name) == 0 {
		return errors.New("id and name must be present")
	}
	if len(ob.Id) > 32 {
		return errors.New("产品ID长度不能超过32")
	}
	if !DeviceIdValid(ob.Id) {
		return errors.New("产品ID格式错误")
	}
	
	rs, err := GetProduct(ob.Id)
	if err != nil {
		return err
	}
	if rs != nil {
		return fmt.Errorf("产品[%s]已存在", ob.Id)
	}

    product := &models.Product{
        Id:          ob.Id,
        Name:        ob.Name,
        TypeId:      ob.TypeId,
        State:       ob.State,
        Desc:        ob.Desc,
		NetworkType: ob.NetworkType,
        CreateId:    ob.CreateId,
        CodecId:     core.Script_Codec,
        MetaData:    ob.MetaData,
		CreateTime:  time.Now(),
    }

	if len(ob.StorePolicy) == 0 {
		product.StorePolicy = core.TIME_SERISE_ES
	}
	
	mc := network.GetNetworkMetaConfig(ob.NetworkType)
	if len(mc.CodecId) > 0 {
		product.CodecId = mc.CodecId
	}

	if len(ob.MetaConfig) == 0 {
		product.MetaConfig = mc.ToJson()
	}

	if err := mysql.DB.Create(product).Error; err != nil {
        return fmt.Errorf("创建产品失败: %v", err)
    }
	_, err = networkmd.BindNetworkProduct(product.Id, product.NetworkType)
	if err != nil {
		logger.Errorf("bind network error: %v", err)
	}
	return err
}

func UpdateProduct(ob *models.ProductModel) error {
	if len(ob.Id) == 0 {
		return errors.New("产品ID不能为空")
	}
	if len(ob.Id) > 32 {
		return errors.New("产品ID长度不能超过32")
	}

	product, err := GetProduct(ob.Id)
	
	if err != nil {
        return errors.New(err.Error())
    }

	if product.AllowView == 1 {
		return errors.New("该产品禁止编辑")
	}
	
	// 构建更新字段
	updates := make(map[string]interface{})
	if len(ob.Name) > 0 {
		updates["name"] = ob.Name
	}
	if len(ob.TypeId) > 0 {
		updates["type_id"] = ob.TypeId
	}
	if ob.MetaData != "" {
		updates["meta_data"] = ob.MetaData
	}
	if ob.MetaConfig != nil {
		metaConfigJSON, _ := json.Marshal(ob.MetaConfig)
		updates["meta_config"] = string(metaConfigJSON)
	}
	if ob.Script != "" {
		updates["script"] = ob.Script
	}
	if ob.Desc != "" {
		updates["desc"] = ob.Desc
	}
	
	// 更新数据
	result := mysql.DB.Model(&models.Product{}).Where("id = ?", ob.Id).Updates(updates)
	
	if result.Error != nil {
		return fmt.Errorf("更新产品失败: %v", result.Error)
	}
	
	return nil
}

func UpdateProductState(ob *models.Product) error {
	if len(ob.Id) == 0 {
		return errors.New("id must be present")
	}
	
	// 使用GORM更新产品状态
	result := mysql.DB.Model(&models.Product{}).
		Where("id = ?", ob.Id).
		Update("state", ob.State)
	
	if result.Error != nil {
		logger.Errorf("update fail %v", result.Error)
		return result.Error
	}
	
	return nil
}

func DeleteProduct(ob *models.Product) error {
	if len(ob.Id) == 0 {
		return errors.New("产品ID不能为空")
	}
	
	product, err := GetProduct(ob.Id)

	if err != nil {
        return errors.New(err.Error())
    }

	// 检查是否允许删除
	if product.AllowView == 1 {
		return errors.New("该产品禁止删除")
	}

	if err := mysql.DB.Delete(&product).Error; err != nil {
		return fmt.Errorf("删除产品失败: %v", err)
	}

	// 解绑网络产品
	if err := networkmd.UnbindNetworkProduct(ob.Id); err != nil {
		logger.Errorf("解绑网络产品失败: %v", err)
	}

	return nil
}


func GetProduct(id string) (*models.ProductModel, error) {
	if len(id) == 0 {
		return nil, errors.New("产品ID不能为空")
	}

	var product models.Product
	result := mysql.DB.Where("id = ?", id).First(&product)
	
	if result.Error != nil {
		if errors.Is(result.Error, gorm.ErrRecordNotFound) {
			return nil, nil
		}
		return nil, fmt.Errorf("查询产品失败: %v", result.Error)
	}

	if product.AllowView == 1 {
		product.Script = ""
	}
	
	m := &models.ProductModel{}
	m.FromEnitty(product)
	
	return m, nil
}

func GetProductMust(id string) (*models.ProductModel, error) {
	p, err := GetProduct(id)
	if err != nil {
		return nil, err
	} else if p == nil {
		return nil, fmt.Errorf("product [%s] not exist", id)
	}
	return p, nil
}